﻿#include "AF_Window.h"
#include "AF_Event.h"
#include "AF_Platform.h"

namespace AF
{
	Window::Window() :
		ATTRIB(FullScreen)(false),
		m_pWndHandle(NULL),
		m_pCurScene(NULL),
		m_pAimScene(NULL),
		m_pTopScene(NULL),
		m_isExitWnd(false),
		m_isShowWnd(false)
	{
		_MEMCPY(&ATTRIB(Size), &AF_SIZE_ZERO, sizeof(Size));

#ifdef AF_FPS_CONTROL
		SetFPS(AF_FPS_DEFAULT);
		m_ttSaveFPST = 0;
		m_ttFPSTUse = 0;
#endif
	}

	Window::~Window()
	{
	}

	bool Window::InitWindow(CreateWindow& cw)
	{
		AF_ASSERT_R(m_pWndHandle == NULL, false);

		m_pWndHandle = OnInitWindow(cw);
			
		if(m_pWndHandle == NULL)
			m_pWndHandle = AF_pTHEPLATFORM->NewWindow(cw);
		
		if(m_pWndHandle == NULL)
			return false;

		ATTRIB(Size).nWidth = cw.nWidth;
		ATTRIB(Size).nHeight = cw.nHeight;
		ATTRIB(FullScreen) = cw.isFullScreen;

		return true;
	}

	bool Window::ShowWindow()
	{
		m_isShowWnd = AF_pTHEPLATFORM->ShowWindow(m_pWndHandle);
		return m_isShowWnd;
	}

	bool Window::RunWindow(Scene* pScene)
	{
		AF_CHECK_R(m_isShowWnd, false);

		m_pAimScene = pScene;

		while(true)
		{
			if(m_pAimScene != m_pCurScene)
			{
				Scene* _pTmpScene = m_pCurScene;
				m_pCurScene = m_pAimScene;

				if(_pTmpScene != NULL)
				{
					// todo:卸载之前的场景??
				}
			}

			if(m_pCurScene == NULL)
				break;

			CallScene(m_pCurScene);
		}

		return true;
	}

	void Window::UpdateWindow()
	{
		return;
	}

	void Window::RenderWindow()
	{
		if(m_pTopScene != NULL)
		{
			RenderScene(m_pTopScene);
		}
		return;
	}

	void Window::FlipWindow()
	{
		AF_pTHEPLATFORM->FlipWindow(m_pWndHandle);
	}

 	void Window::IdleWindow()
 	{
		AF_pTHEAPP->UpdateTimers();
		FPSControl();
 	}

	void Window::TurnScene(Scene* pScene)
	{
		m_pAimScene = pScene;
	}

	int Window::CallScene(Scene* pScene)
	{
		pScene->SetWindow(this);
		int _nRtnVal = pScene->Start(m_pTopScene);

		if(_nRtnVal == AF_ID_OK || _nRtnVal == AF_ID_YES)
		{
			m_pTopScene = pScene;

			AF_pTHEPLATFORM->CleanEventBuffer(m_pWndHandle);

			bool _isDone = false;
			do
			{
				RunScene(pScene);

				if(!pScene->IsExit())
				{
					// 更新绘制对象
					pScene->ResetCanvas();
					// 绘制窗口
					RenderWindow();
					// 翻转窗口
					FlipWindow();
 					// 空闲窗口
 					IdleWindow();

					// 场景转换检查
					if(m_pAimScene != m_pCurScene)
					{
						if(m_pTopScene->Exit())
						{
							_isDone = true;
						}
						else
						{
							m_pAimScene = m_pCurScene;
						}
					}
				}

				_isDone |= pScene->IsExit();

			}while(!_isDone);

			AF_pTHEPLATFORM->CleanEventBuffer(m_pWndHandle);

			m_pTopScene = pScene->GetBackScene();

			_nRtnVal = pScene->End();
		}
		
		return _nRtnVal;
	}

	void Window::RunScene(Scene* pScene)
	{
		static Event _event;
		// 顺序索取所有事件
		while(!pScene->IsExit() && GetEvent(_event))
		{
			if(AF_EVENT_ISCOMMAND(_event.nMessage))
			{
				switch(_event.nMessage)
				{
				case EVENT_KEYBOARD_DOWN:
					pScene->KeyboardDown(_event.lParam1);
					break;
				case EVENT_KEYBOARD_UP:
					pScene->KeyboardUp(_event.lParam1);
					break;
// 				case EVENT_MOUSE_LEFT_DOWN:
// 					pScene->MouseLeftDown(_event.lParam1, _event.lParam2);
// 					break;
// 				case EVENT_MOUSE_LEFT_UP:
// 					pScene->MouseLeftUp(_event.lParam1, _event.lParam2);
// 					break;
// 				case EVENT_MOUSE_RIGHT_DOWN:
// 					pScene->MouseRightDown(_event.lParam1, _event.lParam2);
// 					break;
// 				case EVENT_MOUSE_RIGHT_UP:
// 					pScene->MouseRightUp(_event.lParam1, _event.lParam2);
// 					break;
// 				case EVENT_MOUSE_MOVE:
// 					pScene->MouseMove(_event.lParam1, _event.lParam2);
// 					break;
				default:
					break;
				}
			}
		}

		// 更新
		pScene->Update();
	}

	void Window::RenderScene(Scene* pScene)
	{
		if(!pScene->IsFullWindow())
		{
			Scene* pBackScene = pScene->GetBackScene();

			if(pBackScene != NULL)
			{
				RenderScene(pBackScene);
			}
		}

		pScene->GetCanvas()->Render();
	}




	void Window::SetFPS(UINT nFPS)
	{
		m_nFPS = nFPS;

		if(m_nFPS == 0)
			m_ttFPST = 0;
		else
			m_ttFPST = 1000 / nFPS;
	}

	UINT Window::GetFPS()
	{
		return m_nFPS;
	}

	void Window::SetTitle(const _STRING strTitle)
	{
		AF_pTHEPLATFORM->SetWindowTitle(m_pWndHandle, strTitle);
	}

	bool Window::GetEvent(Event& event)
	{
		event.Reset();

		if(AF_pTHEPLATFORM->GetEvent(m_pWndHandle, event))
		{
			if(AF_EVENT_ISWINDOW(event.nMessage))
			{
				OnGetEvent(event);
				event.nMessage = EVENT_NOTHING;
				return false;
			}
			else if(AF_EVENT_ISCOMMAND(event.nMessage))
			{
				m_pTopScene->OnGetEvent(event);
			}

			return true;
		}

		return false;
	}

	WindowHandle Window::GetHandle()
	{
		return m_pWndHandle;
	}

 	void Window::FPSControl()
 	{
//  		m_ttFPSUse = AF_pTHEPLATFORM->GetTimeTicks() - m_ttSaveFPS;
//  		if(m_ttFPSUse < ATTRIB(FPSTime))
// 		{
// 			AF_pTHEPLATFORM->Delay(ATTRIB(FPSTime) - m_ttFPSUse);
// 		}

// 		AF_NOTE("Use Time = %d\n", AF_pTHEPLATFORM->GetTimeTicks() - m_ttSaveFPS);

#ifdef AF_FPS_CONTROL
		do 
		{
#endif
			AF_pTHEAPP->UpdateExactTimers();
#ifdef AF_FPS_CONTROL
			m_ttFPSTUse = AF_pTHEPLATFORM->GetTimeTicks() - m_ttSaveFPST;
		}while(m_ttFPSTUse < m_ttFPST);
		m_ttSaveFPST = AF_pTHEPLATFORM->GetTimeTicks();
#endif
 	}
}
